\begin{aosachapter}{CMake}{s:cmake}{Bill Hoffman and Kenneth Martin}
%% Based on EN-Revision r229

%% In 1999 the National Library of Medicine engaged a small company
%% called Kitware to develop a better way to configure, build, and deploy
%% complex software across many different platforms. This work was part
%% of the Insight Segmentation and Registration Toolkit, or
%% ITK\footnote{\url{http://www.itk.org/}}.  Kitware, the engineering
%% lead on the project, was tasked with developing a build system that
%% the ITK researchers and developers could use. The system had to be
%% easy to use, and allow for the most productive use of the researchers'
%% programming time. Out of this directive emerged CMake as a replacement
%% for the aging autoconf/libtool approach to building software.  It was
%% designed to address the weaknesses of existing tools while maintaining
%% their strengths.
1999年、米国医療図書館はKitwareという小さな会社と契約した。
各種のプラットフォーム上にまたがる複雑なソフトウェアの
構成やビルド、そしてデプロイをうまくやる仕組みを開発するためである。
この作業は、Insight Segmentation and Registration Toolkit(ITK)\footnote{\url{http://www.itk.org/}}
の一部であった。プロジェクトのエンジニアリングを率いるKitwareの役割は、
ITKの研究者や開発者が使えるようなビルドシステムの開発だった。
このシステムは使いやすくなければならず、
研究者がプログラミングをするときに最も効率的に使えるようにしなければいけなかった。
そんな指令のもとで生まれたCMakeは、
年代物のautoconf/libtoolによる手法を置き換えるためのツールである。
既存のツールの弱みを克服しつつ、その利点だけは維持するように作られている。

%% In addition to a build system, over the years CMake has evolved into a
%% family of development tools: CMake, CTest, CPack, and CDash. CMake is
%% the build tool responsible for building software. CTest is a test
%% driver tool, used to run regression tests. CPack is a packaging tool
%% used to create platform-specific installers for software built with
%% CMake. CDash is a web application for displaying testing results and
%% performing continuous integration testing.
ビルドシステム以外にも、年月を経てCMakeは、各種開発ツールのファミリーへと進化した。
CMake、CTest、CPack、そしてCDashだ。
CMakeはビルドツールで、ソフトウェアのビルドに利用する。
CTestはテストドライバーで、回帰テストを実行するときに使う。
CPackはパッケージングツールで、CMakeでビルドしたソフトウェアに各種プラットフォーム用のインストーラーを作るときに使う。
CDashはウェブアプリケーションで、テスト結果を表示したり継続的インテグレーションを実行したりする。

%% \begin{aosasect1}{CMake History and Requirements}
\begin{aosasect1}{CMakeの歴史と要件}

%% When CMake was being developed, the normal practice for a project was
%% to have a configure script and Makefiles for Unix platforms, and
%% Visual Studio project files for Windows. This duality of build systems
%% made cross-platform development very tedious for many projects: the
%% simple act of adding a new source file to a project was painful. The
%% obvious goal for developers was to have a single unified build system.
%% The developers of CMake had experience with two approaches of solving
%% the unified build system problem.
CMakeの開発が始まったころに一般の開発プロジェクトで使われていた手段は、
Unix系ならconfigureスクリプトとMakefileだし
WindowsならVisual Studioのプロジェクトだった。
このように二通りのビルドシステムがあるおかげで、
クロスプラットフォームの開発はとても面倒くさいものになっていた。
新しいソースファイルをプロジェクトに追加するだけのことでさえ、
手間のかかる作業だった。当然、開発者にとっては
ビルドシステムが統一されたほうがありがたい。
CMakeの開発では、二通りの手法で統一ビルドシステムの問題に立ち向かった。

%% One approach was the VTK build system of 1999.  That system consisted
%% of a configure script for Unix and an executable called \code{pcmaker}
%% for Windows. \code{pcmaker} was a C program that read in Unix
%% Makefiles and created NMake files for Windows.  The binary executable
%% for \code{pcmaker} was checked into the VTK CVS system repository.  Several
%% common cases, like adding a new library, required changing that source
%% and checking in a new binary.
%% Although this was a unified system in some sense, it had many
%% shortcomings.
そのひとつが、1999年のVTKビルドシステムだ。
このシステムは、Unix用のconfigureスクリプトとWindows用の実行ファイル
\code{pcmaker}で構成されている。
\code{pcmaker}はCで書かれたプログラムで、
UnixのMakefileを読み込んでWindows用のNMakeファイルを出力する。
\code{pcmaker}の実行ファイルはVTK CVSシステムリポジトリにチェックインされていた。
新しいライブラリを追加するなどのありがちな作業をするにも、
ソースを変更して新しいバイナリをチェックインする必要があった。
ある意味では統一システムと言えなくもなかったが、問題も多かった。

%% The other approach the developers had experience with was a
%% \code{gmake} based build system for TargetJr.  TargetJr was a C++
%% computer vision environment originally developed on Sun
%% workstations. Originally TargetJr used the \code{imake} system to
%% create Makefiles. However, at some point, when a Windows port was
%% needed, the \code{gmake} system was created. Both Unix compilers and
%% Windows compilers could be used with this \code{gmake}-based system.
%% The system required several environment variables to be set prior to
%% running \code{gmake}.  Failure to have the correct environment caused
%% the system to fail in ways that were difficult to debug, especially
%% for end users.
開発者が使ったもうひとつの手法は、TargetJr用の
\code{gmake}ベースのビルドシステムだった。
TargetJrはC++で書かれた画像処理環境で、
当初はSunのワークステーション上で開発されていた。
そのころのTargetJrは、\code{imake}システムでMakefileを作っていた。
Windowsへの移植が必要になったときに作られたのが\code{gmake}システムだ。
UnixのコンパイラもWindowsのコンパイラも、
どちらもこの\code{gmake}ベースのシステムを使える。
このシステムでは、\code{gmake}を実行する前に環境変数の設定が必要となる。
環境変数を正しく設定しないと実行に失敗し、その原因を突き止めるのは
(特にエンドユーザーにとっては)とても難しい。

%% Both of these systems suffered from a serious flaw: they forced
%% Windows developers to use the command line. Experienced Windows
%% developers prefer to use integrated development environments (IDEs).
%% This would encourage Windows developers to create IDE files by hand
%% and contribute them to the project, creating the dual build system
%% again.  In addition to the lack of IDE support, both of the systems
%% described above made it extremely difficult to combine software
%% projects. For example, VTK (\aosachapref{s:vtk}) had very few modules for reading images
%% mostly because the build system made it very difficult to use
%% libraries like libtiff and libjpeg.
どちらのシステムにも深刻な問題があった。
Windowsの開発者にコマンドラインを使わせる必要があるということだ。
Windowsの開発者はIDE(統合開発環境)を使いたがることが多い。
その結果どうなったかというと、Windowsの開発者はIDE用のファイルを手で書いて
それをプロジェクトに追加するようになった。
2系統のビルドシステムが存在する時代に逆戻りだ。
IDE対応の問題以外にも、先述のふたつのシステムには
複数のプロジェクトを組み合わせるのがとてつもなく難しいという問題もあった。
たとえばVTK (\aosachapref{s:vtk})には、画像を読み込むモジュールが決定的に欠けていた。
このシステムではlibtiffやlibjpegといったライブラリを使うのがとても難しかったのだ。

%% It was decided that a new build system would be developed for ITK and
%% C++ in general. The basic constraints of the new build system would be
%% as follows:
そこで、ITKとC++用の汎用的なビルドシステムを新たに開発することになった。
新たに作るシステムに必要とされた要件は、次のようなものだ。

\begin{aosaitemize}

  %% \item Depend only on a C++ compiler being installed on the system.
  \item システムにインストールされているC++コンパイラだけに依存すること。

  %% \item It must be able to generate Visual Studio IDE input files.
  \item Visual Studio IDE用のファイルを生成できること。

  %% \item It must be easy to create the basic build system targets,
  %%   including static libraries, shared libraries, executables, and
  %%   plugins.
  \item 基本的なビルドシステムターゲット(スタティックライブラリ・共有ライブラリ・
  実行ファイル・プラグインなど)を簡単に作れること。

  %% \item It must be able to run build time code generators.
  \item ビルド時にコードジェネレーターを実行できること。

  %% \item It must support separate build trees from the source tree.
  \item ひとつのソースツリー内で複数のビルドツリーに分割できること。

  %% \item It must be able to perform system introspection, i.e.,
  %%   be able to determine automatically what the target system
  %%   could and could not do.
  \item システムのイントロスペクションができること。
  つまり、ターゲットシステム上で何ができて何ができないのかを自動判別できること。

  %% \item It must do dependency scanning of C/C++ header files
  %%   automatically.
  \item C/C++ヘッダファイルの依存関係を自動的にスキャンできること。

  %% \item All features would need to work consistently and equally well
  %%   on all supported platforms.
  \item すべての機能が、どのプラットフォームでも同じように安定して動作すること。

\end{aosaitemize}

%% In order to avoid depending on any additional libraries and parsers,
%% CMake was designed with only one major dependency, the C++ compiler
%% (which we can safely assume we have if we're building C++ code). At the
%% time, building and installing scripting languages like Tcl was difficult
%% on many popular UNIX and Windows systems. It can still be an
%% issue today on modern supercomputers and secured computers with no
%% Internet connection, so it can still be difficult to build third-party
%% libraries. Since the build
%% system is such a basic requirement for a package, it was decided that no
%% additional dependencies would be introduced into CMake. This
%% did limit CMake to creating its own simple language, which is a choice
%% that still causes some people to dislike CMake. However, at the time
%% the most popular embedded language was Tcl. If CMake had been a
%% Tcl-based build system, it is unlikely that it would have gained the
%% popularity that it enjoys today.
外部のライブラリやパーサーへの依存を回避するため、CMakeはC++コンパイラだけに
依存するように設計した(C++のコードをビルドするならC++コンパイラは必ずあるだろうという前提だ)。
その当時は、Tclのようなスクリプト言語の環境をUNIXやWindows上に用意するのは
簡単ではなかったのだ。また、現代であっても、
モダンなスーパーコンピューターやインターネットから隔離されたセキュアなコンピューターなど、
サードパーティのライブラリをビルドしづらい環境は存在する。
ビルドシステムはパッケージの基本要件なので、CMakeには
コンパイラ以外の依存関係を持ち込まないように決めたのだ。
そのせいでCMake用のシンプルな言語を作ることができなくて、
それが原因でCMakeを嫌っている人もいる。
しかし、その当時最もよく使われていた組み込み用言語がTclであったことを思い出そう。
もしあのときCMakeがTclベースのビルドシステムを作っていたら、
これほどまでに広まることがあっただろうか？

%% The ability to generate IDE project files is a strong selling point
%% for CMake, but it also limits CMake to providing only the features
%% that the IDE can support natively.  However, the benefits of providing
%% native IDE build files outweigh the limitations.  Although this
%% decision made the development of CMake more difficult, it made the
%% development of ITK and other projects using CMake much easier.
%% Developers are happier and more productive when using the tools they
%% are most familiar with.  By allowing developers to use their preferred
%% tools, projects can take best advantage of their most important
%% resource: the developer.
IDE用のプロジェクトファイルの生成機能は、CMakeの強いセールスポイントとなる。
しかし同時に、CMakeで提供できる機能がIDEがネイティブサポートする機能だけに制限されてしまう。
ただ、そんな制限よりもIDE用のビルドファイルを提供できる利点のほうがずっと上回る。
この方針にしたおかげでCMake自体の開発は難しくなったが、
ITKやその他のプロジェクトでのCMakeを使った開発がとても簡単になった。
開発者にとっては、使いなれたツールを使えるというのは
ありがたいことだし生産性も上がるというものだ。
開発者が自分の好みのツールを使えるようにしたおかげで、
開発プロジェクトで最も大切なリソースである「開発者」
が大きなアドバンテージを得られるようになった。

%% All C/C++ programs require one or more of the following fundamental
%% building blocks of software: executables, static libraries, shared
%% libraries, and plugins. CMake had to provide the ability to create
%% these products on all supported platforms. Although all platforms
%% support the creation of those products, the compiler flags used to
%% create them vary greatly from compiler to compiler and platform to
%% platform.  By hiding the complexity and platform differences behind a
%% simple command in CMake, developers are able to create them on
%% Windows, Unix and Mac. This ability allows developers to focus on the
%% project rather than on the details of how to build a shared library.
すべてのC/C++プログラムは、実行ファイルかスタティックライブラリ、
共有ライブラリ、プラグインのいずれかをビルドすることになる。
CMakeの機能を使えば、これらのプロダクトをすべての対応プラットフォーム上で作成できる。
すべてのプラットフォームがこれらのプロダクトの作成に対応しているとはいえ、
そのときに使うコンパイルフラグはコンパイラによって異なるし、
プラットフォームによっても異なる。
その複雑性やプラットフォーム間の差異をCMakeのシンプルなコマンドの裏側に
隠すことで、開発者はWindowsやUnixそしてMac上での開発ができるようになる。
プロジェクトそのものの開発に注力でき、
共有ライブラリをビルドする方法などの細かいことは意識せずに済むのだ。

%% Code generators provide added complexity to a build system.  From the
%% start, VTK provided a system that automatically wrapped the
%% C++ code into Tcl, Python, and Java by
%% parsing the C++ header files, and automatically generating a wrapping
%% layer.  This requires a build system that can build a C/C++ executable
%% (the wrapper generator), then run that executable at build time to
%% create more C/C++ source code (the wrappers for the particular
%% modules).  That generated source code must then be compiled into
%% executables or shared libraries. All of this has to happen within the
%% IDE environments and the generated Makefiles.
コードジェネレータを搭載しようとすると、ビルドシステムはさらに複雑になる。
VTKには当初から、C++のコードを自動的にラップしてTclやPythonそしてJavaで
使えるようにするシステムがあった。これは、C++のヘッダーファイルを解析して
ラッピングレイヤーを自動生成するものである。そのためには、C/C++の
実行ファイルをビルドできるビルドシステム(ラッパージェネレータ)が必要となり、
ビルド時にそれを実行してC/C++のソースコード
(何らかのモジュール用のラッパー)を生成することになる。
そして、生成されたソースコードをコンパイルして
実行ファイルなり共有ライブラリなりを生成しなければいけない。
これらすべてを、IDE環境や自動生成されたMakefile
で行う必要があるのだ。

%% When developing flexible cross-platform C/C++ software, it is
%% important to program to the features of the system, and not to the
%% specific system. Autotools has a model for doing system introspection
%% which involves compiling small snippets of code, inspecting and
%% storing the results of that compile. Since CMake was meant to be
%% cross-platform it adopted a similar system introspection technique.
%% This allows developers to program to the canonical system instead of
%% to specific systems. This is important to make future portability
%% possible, as compilers and operating systems change over time.  For
%% example, code like this:
柔軟なクロスプラットフォーム対応のC/C++ソフトウェアを開発する際に重要なのは、
システムの機能をプログラムするのであって特定のシステムをプログラムするのではないということだ。
Autotoolsがシステムの状態を把握するために使っているモデルは、
ちょっとしたコード片をコンパイルし、その結果を調べて保存しておくというものだ。
CMakeはクロスプラットフォーム対応を目指しているので、
同様のテクニックでシステムの状態を調べることにした。
これで開発者は、個々のシステムへの対応を気にせず
システム本来の機能のプログラムができるようになる。
これは、将来のポータビリティを確保するためにも重要だ。
というのも、コンパイラやOSは時とともに変わっていくものだからである。
たとえば、こんなコードを考えてみよう。

%% \begin{verbatim}
%% #ifdef linux
%% // do some linux stuff
%% #endif
%% \end{verbatim}
\begin{verbatim}
#ifdef linux
// Linux関連の処理
#endif
\end{verbatim}

%% \noindent Is more brittle than code like this:
\noindent このコードよりも、次のコードのほうが崩れにくい。

%% \begin{verbatim}
%% #ifdef HAS_FEATURE
%% // do something with a feature
%% #endif
%% \end{verbatim}
\begin{verbatim}
#ifdef HAS_FEATURE
// 何かの機能を使った処理
#endif
\end{verbatim}

%% Another early CMake requirement also came from autotools: the ability
%% to create build trees that are separate from the source tree. This
%% allows for multiple build types to be performed on the same source
%% tree. It also prevents the source tree from being cluttered with build
%% files, which often confuses version control systems.
初期のCMakeの要件には、autotoolsから引き継いだものがもうひとつあった。
それが、ソースツリーとは別にビルドツリーを作れる機能である。
この機能を使えば、同じソースツリーに複数のビルド形式を構築できる。
また、ソースツリーとビルドファイルがごちゃごちゃになってしまうことも防げる。
ごちゃごちゃになってしまえば、バージョン管理システムも混乱してしまう。

%% One of the most important features of a build system is the ability to
%% manage dependencies. If a source file is changed, then all products
%% using that source file must be rebuilt. For C/C++ code, the header
%% files included by a \code{.c} or \code{.cpp} file must also be checked
%% as part of the dependencies.  Tracking down issues where only some of
%% the code that should be compiled actually gets compiled as a result of
%% incorrect dependency information can be time consuming.
ビルドシステムで最も重要な機能のひとつが、依存関係の管理である。
あるソースファイルを変更したら、そのソースファイルを使っている
すべてのプロダクトを再ビルドしなければならない。
C/C++のコードなら、\code{.c}ファイルあるいは\code{.cpp}ファイルから
インクルードしているヘッダファイルの変更もチェックする必要がある。
本来コンパイルすべきコードの中にコンパイル漏れがあったせいで
依存関係の情報がおかしくなったなどという問題の原因を追うのは
時間の無駄だ。

%% All of the requirements and features of the new build system had to
%% work equally well on all supported platforms. CMake needed to provide
%% a simple API for developers to create complicated software systems
%% without having to understand platform details. In effect, software
%% using CMake is outsourcing the build complications to the CMake
%% team. Once the vision for the build tool was created with the basic
%% set of requirements, implementation needed to proceed in an agile way.
%% ITK needed a build system almost from day one. The first versions of
%% CMake did not meet all of the requirements set out in the vision, but
%% they were able to build on Windows and Unix.
新しく作るビルドシステムは、
これまでにあげたすべての要件や機能を
すべての対応プラットフォームで同様に実現する必要があった。
CMakeに求められたのは、開発者が複雑なソフトウェアシステムを作るときに
プラットフォームの詳細を知らなくても済むようなシンプルなAPIだった。
事実上、CMakeを使っているソフトウェアは
ビルドに関する複雑なあれこれを
CMakeチームにアウトソースしているに等しい。
これらの基本要件に基づいたビジョンができあがったら、
その実装をアジャイル手法で進めていくなければいけなかった。
というのも、ITKは新しいビルドシステムをすぐにでも必要としていたのだ。
最初のバージョンのCMakeはここまでにあげた要件をすべて満たしているわけではなかったが、
WindowsとUnix上でのビルドはできるものだった。

\end{aosasect1}

%% \begin{aosasect1}{How CMake Is Implemented}
\begin{aosasect1}{CMakeの実装方法}

%% As mentioned, CMake's development languages are C and C++. To explain
%% its internals this section will first describe the CMake process from
%% a user's point of view, then examine its structures.
先述の通り、CMake自体の開発に使った言語はCとC++である。
その内部を解説するにあたって、このセクションではまずCMakeの動きを
ユーザーの視点から説明する。それから、その構造を見ていこう。

%% \begin{aosasect2}{The CMake Process}
\begin{aosasect2}{CMakeの処理工程}

%% CMake has two main phases. The first is the ``configure'' step, in which
%% CMake processes all the input given to it and creates an internal
%% representation of the build to be performed. Then next phase is the
%% ``generate'' step. In this phase the actual build files are created.
CMakeには、主要なフェーズが二つある。まず最初が``構成(configure)''で、
ここではCMakeがすべての入力を処理し、
ビルドを実行するための内部表現を生成する。
次のフェーズが``生成(generate)''で、
実際のビルドファイルをここで生成する。

%% \begin{aosasect3}{Environment Variables (or Not)}
\begin{aosasect3}{環境変数(またはそれ以外の変数)}

%% In many build systems in 1999, and even today, shell level environment
%% variables are used during the build of a project. It is typical that a
%% project has a PROJECT\_ROOT environment variable that points to the
%% location of the root of the source tree.  Environment variables are
%% also used to point to optional or external packages. The trouble with
%% this approach is that for the build to work, all of these external
%% variables need to be set each time a build is performed. To solve this
%% problem CMake has a cache file that stores all of the variables
%% required for a build in one place. These are not shell or environment
%% variables, but CMake variables. The first time CMake is run for a
%% particular build tree, it creates a \code{CMakeCache.txt} file which
%% stores all the persistent variables for that build. Since the file is
%% part of the build tree, the variables will always be available to
%% CMake during each run.
1999年当時に限らず現在でも、プロジェクトのビルドの際に
シェルの環境変数が使われている。よくありがちな使い方は、
環境変数PROJECT\_ROOTでソースツリーのルートの場所を表すといったものだ。
環境変数は、オプションパッケージや外部パッケージの場所を表すときにも用いられる。
この手法の問題は、ビルドのたびにこれらの環境変数を設定しないと
ビルドがうまくいかないということだ。この問題を解決するために、
CMakeはキャッシュファイルを作っている。
このキャッシュファイルに、ビルドに必要なすべての変数を格納しているのだ。
シェルの環境変数などではなく、CMake独自の変数である。
あるビルドツリー上で最初にCMakeを実行したときに
\code{CMakeCache.txt}というファイルを作って、
そこにビルド用の変数をすべて格納する。
このファイル自体もビルドツリーの一員なので、
CMakeを実行するたびにその内容を参照できる。

\end{aosasect3}

%% \begin{aosasect3}{The Configure Step}
\begin{aosasect3}{構成ステップ}

%% During the configure step, CMake first reads the \code{CMakeCache.txt}
%% if it exists from a prior run.  It then reads \code{CMakeLists.txt},
%% found in the root of the source tree given to CMake. During the
%% configure step, the \code{CMakeLists.txt} files are parsed by the
%% CMake language parser. Each of the CMake commands found in the file is
%% executed by a command pattern object. Additional \code{CMakeLists.txt}
%% files can be parsed
%% during this step by the \code{include} and \code{add\_subdirectory}
%% CMake commands.
%% CMake has a C++ object for each of the commands that can be used in
%% the CMake language. Some examples of commands are \code{add\_library},
%% \code{if}, \code{add\_executable}, \code{add\_subdirectory}, and
%% \code{include}. In effect, the entire language of CMake is implemented
%% as calls to commands. The parser simply converts the CMake input files
%% into command calls and lists of strings that are arguments to
%% commands.
構成ステップでは、まず最初に前回実行したときの\code{CMakeCache.txt}
があるかどうかを調べ、存在すればそれを読み込む。それに続いて、
ソースツリーのルートにある\code{CMakeLists.txt}を読み込む。
構成ステップで\code{CMakeLists.txt}をパースするのはCMake言語パーサーだ。
このファイル内で見つかったCMakeコマンドを、コマンドパターンオブジェクトが実行する。
このステップでさらに別の\code{CMakeLists.txt}ファイルをパースさせることもできる。
そのために使えるCMakeのコマンドが\code{include}と\code{add\_subdirectory}だ。
CMakeは個々のコマンドに対応するC++のオブジェクトを持っており、
これをCMake言語から使えるようになっている。たとえば
\code{add\_library}や\code{if}、\code{add\_executable}、
\code{add\_subdirectory}、そして\code{include}といったコマンドがある。
事実上、CMake言語はこれらのコマンドの呼び出しで実装されている。
パーサーは、単純にCMakeの入力ファイルをコマンド呼び出しに変換するだけであり、
文字列のリストはそれらのコマンドへの引数となる。

%% The configure step essentially ``runs'' the user-provided CMake
%% code. After all of the code is executed, and all cache variable values
%% have been computed, CMake has an in-memory representation of the
%% project to be built. This will include all of the libraries,
%% executables, custom commands, and all other information required to
%% create the final build files for the selected generator. At this
%% point, the \code{CMakeCache.txt} file is saved to disk for use in
%% future runs of CMake.
構成ステップは本質的に、ユーザーが指定したCMakeのコードを
``実行''するステップだ。すべてのコードを実行して
キャッシュ変数の値を算出し終えたら、
CMakeはそのプロジェクトのインメモリ表現を得たことになる。
この中にはすべてのライブラリや実行ファイルそしてカスタムコマンドが含まれており、
選んだジェネレータで最終的にビルドするために必要な情報がすべて含まれている。
この時点で\code{CMakeCache.txt}ファイルを保存し、
次にCMakeを実行したときに使えるようにする。

%% The in-memory representation of the project is a collection of
%% targets, which are simply things that may be built, such as
%% libraries and executables. CMake also supports custom
%% targets: users can define their inputs and outputs, and provide
%% custom executables or scripts to be run at build time. CMake
%% stores each target in a \code{cmTarget} object. These objects are
%% stored in turn in the \code{cmMakefile} object, which is basically a
%% storage place for all of the targets found in a given directory of the
%% source tree. The end result is a tree of \code{cmMakefile} objects
%% containing maps of \code{cmTarget} objects. 
プロジェクトのインメモリ表現とはターゲットの集まりである。
ターゲットとは単にビルド対象のものを指す。ライブラリや実行ファイルなどである。
CMakeはカスタムターゲットもサポートしている。
ユーザーが自分で入出力を定義し、ビルド時に実行する
カスタムコマンドやスクリプトを用意すればよい。
CMakeは、各ターゲットを\code{cmTarget}オブジェクトに格納する。
そして、これらのオブジェクトがさらに\code{cmMakefile}オブジェクトに格納される。
\code{cmMakefile}オブジェクトは基本的に、ソースツリー内の指定したディレクトリにある
すべてのターゲットを格納するものである。最終的にできあがるのは
\code{cmMakefile}オブジェクトのツリーで、その中に
\code{cmTarget}オブジェクトのマップが含まれている。

\end{aosasect3}

%% \begin{aosasect3}{The Generate Step}
\begin{aosasect3}{生成ステップ}

%% Once the configure step has been completed, the generate step can take
%% place. The generate step is when CMake creates the build files for the
%% target build tool selected by the user. At this point the internal
%% representation of targets (libraries, executables, custom targets) is
%% converted to either an input to an IDE build tool like Visual Studio,
%% or a set of Makefiles to be executed by \code{make}. CMake's internal
%% representation after the configure step is as generic as possible so
%% that as much code and data structures as possible can be shared
%% between different built tools.
構成ステップが完了したら、次は生成ステップの出番だ。
このステップは、ユーザーが選んだターゲットビルドツール用のビルドファイルを
CMakeが生成する。この時点で、ターゲット(ライブラリ・実行ファイル・カスタムターゲット)
の内部表現を変換して、Visual StudioなどのIDE用のファイルあるいは
\code{make}で実行するためのMakefile群にする。構成ステップを終えた時点での
CMakeの内部表現は可能な限り汎用的な形式にしており、
異なるビルドツール間でもできるだけ多くのコードやデータ構造を共有できるようにしている。

%% An overview of the process can be seen in \aosafigref{fig.cma.pro}.
これらの工程の概要を\aosafigref{fig.cma.pro}に示す。

%% \aosafigure[200pt]{../images/cmake/process.eps}{Overview of the CMake Process}{fig.cma.pro}
\aosafigure[200pt]{../images/cmake/process.eps}{CMakeの処理工程の概要}{fig.cma.pro}

\end{aosasect3}

\end{aosasect2}

%% \begin{aosasect2}{CMake: The Code}
\begin{aosasect2}{CMake: そのコード}

%% \begin{aosasect3}{CMake Objects}
\begin{aosasect3}{CMakeのオブジェクト群}

%% CMake is an object-oriented system using inheritance, design patterns
%% and encapsulation.  The major C++ objects and their relationships can
%% be seen in \aosafigref{fig.cma.obj}.
CMakeはオブジェクト指向のシステムで、継承やデザインパターンそしてカプセル化などの
テクニックを駆使している。主要なC++オブジェクトとその間の関連を\aosafigref{fig.cma.obj}
に示す。

%% \aosafigureTop[350pt]{../images/cmake/objects.eps}{CMake Objects}{fig.cma.obj}
\aosafigureTop[350pt]{../images/cmake/objects.eps}{CMakeのオブジェクト群}{fig.cma.obj}

%% The results of parsing each \code{CMakeLists.txt} file are stored in
%% the \code{cmMakefile} object. In addition to storing the information
%% about a directory, the \code{cmMakefile} object controls the parsing
%% of the \code{CMakeLists.txt} file. The parsing function calls an
%% object that uses a lex/yacc-based parser for the CMake language.
%% Since the CMake language syntax changes very infrequently, and lex and yacc
%% are not always available on systems where CMake is being built, the
%% lex and yacc output files are processed and stored in the
%% \code{Source} directory under version control with all of the other
%% handwritten files.
各所の\code{CMakeLists.txt}ファイルをパースした結果は\code{cmMakefile}オブジェクトに格納する。
そのディレクトリに関する情報を保持するだけでなく、\code{cmMakefile}
オブジェクトは\code{CMakeLists.txt}ファイルのパースも担当する。
パース関数がこのオブジェクトを呼び、このオブジェクトがlex/yaccベースのパーサでCMake言語を処理する。
CMake言語構文が変わることはほとんどないし、CMake自体をビルドするシステム上でlexやyaccが常に使えるとは限らない。
そこで、事前にlexとyaccで処理したファイルもバージョン管理システムの\code{Source}
ディレクトリに格納している。

%% Another important class in CMake is \code{cmCommand}. This is the base
%% class for the implementation of all commands in the CMake
%% language. Each subclass not only provides the implementation for the
%% command, but also its documentation. As an example, see the
%% documentation methods on the \code{cmUnsetCommand} class:
CMakeで重要なもう一つのクラスが\code{cmCommand}である。
これは、CMake言語の全コマンドの実装時に基底クラスとして用いるものだ。
各サブクラスにはコマンドの実装だけでなくそのドキュメントも含まれている。
例として、\code{cmUnsetCommand}クラスのドキュメント用メソッドを紹介する。

\pagebreak

\begin{verbatim}
virtual const char* GetTerseDocumentation()
{
    return "Unset a variable, cache variable, or environment variable.";
}

/**
 * More documentation.
 */

virtual const char* GetFullDocumentation()
{
    return
      "  unset(<variable> [CACHE])\n"
      "Removes the specified variable causing it to become undefined.  "
      "If CACHE is present then the variable is removed from the cache "
      "instead of the current scope.\n"
      "<variable> can be an environment variable such as:\n"
      "  unset(ENV{LD_LIBRARY_PATH})\n"
      "in which case the variable will be removed from the current "
      "environment.";
}
\end{verbatim}

\end{aosasect3}

%% \begin{aosasect3}{Dependency Analysis}
\begin{aosasect3}{依存関係の解析}

%% CMake has powerful built-in dependency analysis capabilities for
%% individual Fortran, C and C++ source code files. Since Integrated
%% Development Environments (IDEs) support and maintain file dependency
%% information, CMake skips this step for those build systems. For IDE
%% builds, CMake creates a native IDE input file, and lets the IDE handle
%% the file level dependency information. The target level dependency information
%% is translated to the IDE's format for specifying dependency information.
CMakeには強力な依存関係解析機能が組み込まれており、FortranやCそしてC++
のソースファイルを解析できる。統合開発環境(IDE)は自前でファイルの依存関係を管理しているので、
IDE向けのビルドの場合はCMakeでの依存関係解析処理をスキップする。
IDE向けのビルドでは、CMakeはIDEネイティブの入力ファイルを生成し、
ファイルレベルの依存関係情報はIDEに処理させる。
ターゲットレベルの依存関係情報は、IDE向けのフォーマットに変換して指定する。

%% With Makefile-based builds, native make programs do not know how to
%% automatically compute and keep dependency information up-to-date. For
%% these builds, CMake automatically computes dependency information for
%% C, C++ and Fortran files. Both the generation and maintenance of these
%% dependencies are automatically done by CMake. Once a project is
%% initially configured by CMake, users only need to run \code{make} and
%% CMake does the rest of the work.
Makefileベースのビルドの場合、make自体には依存関係を最新の状態に保つ機能がない。
そこで、この場合はCMakeが自動的にC・C++・Fortranのファイルの依存関係を算出する。
依存情報の生成や最新の状態への追従は、CMakeが自動的に行うということだ。
プロジェクトを最初にCMakeで構成すれば、あとは単に\code{make}
を実行するだけでよい。残りの作業はすべてCMakeがやってくれる。

%% Although users do not need to know how CMake does this work, it may be
%% useful to look at the dependency information files for a project. This
%% information for each target is stored in four files called
%% \code{depend.make}, \code{flags.make}, \code{build.make}, and
%% \code{DependInfo.cmake}.  \code{depend.make} stores the dependency
%% information for all the object files in the directory.
%% \code{flags.make} contains the compile flags used for the source files
%% of this target. If they change then the files will be recompiled.
%% \code{DependInfo.cmake} is used to keep the dependency information
%% up-to-date and contains information about what files are part of the
%% project and what languages they are in. Finally, the rules for
%% building the dependencies are stored in \code{build.make}. If a
%% dependency for a target is out of date then the depend information
%% for that target will be recomputed, keeping the dependency information
%% current. This is done because a change to a .h file could add a new
%% dependency.
ユーザーはCMakeがどのように動いているかなど知る必要もないが、
プロジェクトの依存情報のファイルがどのようになっているかは見る価値があるだろう。
各ターゲット用の依存情報は\code{depend.make}、\code{flags.make}、
\code{build.make}、そして\code{DependInfo.cmake}の4つのファイルに格納されている。
\code{depend.make}には、ディレクトリ内のすべてのオブジェクトファイルの依存情報を保存する。
\code{flags.make}には、このターゲットのソースファイルに使う
コンパイルフラグを保存する。この内容が変わったら、ファイルが再コンパイルされる。
\code{DependInfo.cmake}は、依存情報を最新に保つために利用する。
また、プロジェクトに属するファイルがどれでそこにどんな言語を使っているのか
といった情報もこのファイルに含まれる。
最後に、依存関係を構築するためのルールが\code{build.make}
に保存される。あるターゲット用の依存情報が古くなると
そのターゲット用の依存情報を再度算出し、依存情報を最新の状態に保つ。
その理由は、.hファイルに変更があれば新たな依存関係が増える可能性があるからである。

\end{aosasect3}

%% \begin{aosasect3}{CTest and CPack}
\begin{aosasect3}{CTestおよびCPack}

%% Along the way, CMake grew from a build system into
%% a family of tools for building, testing, and packaging
%% software. In addition to command line \code{cmake}, and the CMake GUI
%% programs, CMake ships with a testing tool CTest, and a packaging tool
%% CPack. CTest and CPack shared the same code base as CMake, but are
%% separate tools not required for a basic build.
現在に至るまでにCMakeは成長を続け、単なるビルドシステムではなく
ビルド・テスト・パッケージングなどのツールをまとめたシステムになった。
コマンドラインツールである\code{cmake}やGUIプログラムのCMake
に加えて、テスティングツールであるCTestやパッケージングツールであるCPack
なども一緒に配布されている。CTestやCPackはCMake
と同じコードベースを共有しているがCMakeとは別のツールであり、
基本的なビルドをする上では必須ではない。

%% The \code{ctest} executable is used to run regression tests. A project
%% can easily create tests for CTest to run with the \code{add\_test}
%% command. The tests can be run with CTest, which can also be used to
%% send testing results to the CDash application for viewing on the web.
%% CTest and CDash together are similar to the Hudson testing tool. They
%% do differ in one major area: CTest is designed to allow a much more
%% distributed testing environment.  Clients can be setup to pull source
%% from version control system, run tests, and send the results to
%% CDash. With Hudson, client machines must give Hudson ssh access to the
%% machine so tests can be run.
実行ファイル\code{ctest}を使えば回帰テストを実行できる。
CTest用のテストを作るのも簡単で、\code{add\_test}コマンドを使えばよい。
テストを実行するときにCTestも使え、これを使ってテスト結果を
CDashアプリケーションに送ればウェブで確認できるようになる。
CTestとCDashの組み合わせは、テスティングツールであるHudsonと似ている。
が、大きく異なる点がひとつある。
CTestは、より分散したテスト環境を構築できるように作られている。
クライアントがバージョン管理システムからソースを取得して
テストを実行し、その結果をCDashに送信するといったものだ。
Hudsonの場合は、クライアントマシンへのsshアクセス権をHudsonに
渡さなければテストを実行できない。

%% The \code{cpack} executable is used to create installers for
%% projects. CPack works much like the build part of CMake: it interfaces
%% with other packaging tools. For example, on Windows the NSIS packaging
%% tool is used to create executable installers from a project. CPack
%% runs the install rules of a project to create the install tree, which
%% is then given to a an installer program like NSIS\@.  CPack also
%% supports creating RPM, Debian \code{.deb} files, \code{.tar},
%% \code{.tar.gz} and self-extracting tar files.
実行ファイル\code{cpack}を使うと、プロジェクトのインストーラーを作れる。
CPackの動きはCMakeのビルド部と似ている。他のパッケージングツールとの橋渡し役となるのだ。
たとえばWindowsの場合は、パッケージングツールNSISを使ってプロジェクトのインストーラーを作る。
CPackはプロジェクトのインストールルールに基づいてインストールツリーを作り、
これをNSISのようなインストーラー作成プログラムに渡す。CPackがその他に対応しているのは、
RPMやDebian \code{.deb}ファイル、\code{.tar}、\code{.tar.gz}そして
自己展開形式のtarファイルである。

\end{aosasect3}

\end{aosasect2}

%% \begin{aosasect2}{Graphical Interfaces}
\begin{aosasect2}{グラフィカルインターフェイス}

%% The first place many users first see CMake is one of CMake's user
%% interface programs. CMake has two main user interface programs:
%% a windowed Qt-based application, and a command line
%% curses graphics-based application. These GUIs are
%% graphical editors for the \code{CMakeCache.txt} file. They are
%% relatively simple interfaces with two buttons, configure and
%% generate, used to trigger the main phases of the CMake process. The
%% curses-based GUI is available on Unix TTY-type platforms and
%% Cygwin. The Qt GUI is available on all platforms.  The GUIs can be
%% seen in \aosafigref{fig.cma.gui1} and \aosafigref{fig.cma.gui2}.
多くのユーザーにとって、CMakeで最初に目にするのはCMakeの
ユーザーインターフェイスプログラムだ。CMakeには二種類の
インターフェイスがある。Qtベースのウィンドウアプリケーションと
コマンドラインのcursesベースのアプリケーションだ。
これらのGUIは、\code{CMakeCache.txt}ファイル用のグラフィカルなエディタである。
インターフェイスは比較的シンプルで、configure(構成)とgenerate(生成)
の二つのブタンがあるだけである。これらを使って、
CMakeのそれぞれの工程を実行する。curseベースのGUIは、
Unix系のTTYプラットフォームやCygwinで使える。
QtのGUIは、すべてのプラットフォームで使える。それぞれのGUIの様子を
\aosafigref{fig.cma.gui1}と\aosafigref{fig.cma.gui2}に示す。

%% \aosafigure[250pt]{../images/cmake/GUI1.eps}{Command Line Interface}{fig.cma.gui1}
\aosafigure[250pt]{../images/cmake/GUI1.eps}{コマンドラインのインターフェイス}{fig.cma.gui1}

%% \aosafigure[250pt]{../images/cmake/GUI2.eps}{Graphics-based Interface}{fig.cma.gui2}
\aosafigure[250pt]{../images/cmake/GUI2.eps}{グラフィックベースのインターフェイス}{fig.cma.gui2}

%% Both GUIs have cache variable names on the left, and values on the
%% right. The values on the right can be changed by the user to values
%% that are appropriate for the build. There are two types of
%% variables, normal and advanced. By default the normal variables are
%% shown to the user. A project can determine which variables are
%% advanced inside the \code{CMakeLists.txt} files for the project. This
%% allows users to be presented with as few choices as necessary for a
%% build.
どちらのインターフェイスでも、キャッシュ変数の名前が左側にあって
その値が右側にある。右側の値は、ユーザーが適切な値に変更できる。
変数には、ノーマルとアドバンストの二種類がある。
デフォルトでは、ノーマル変数がユーザーに表示される。
どの変数がノーマルでどの変数がアドバンストかは、
そのプロジェクトの\code{CMakeLists.txt}ファイルの中で決める。
これで、ビルドに必要な変数だけをユーザーに見せるようにできる。

%% Since cache values can be modified as the commands are executed, the
%% process of converging on a final build can be iterative. For example,
%% turning on an option may reveal additional options. For this reason,
%% the GUI disables the ``generate'' button until the user has had a
%% chance to see all options at least once. Each time the configure
%% button is pressed, new cache variables that have not yet been
%% presented to the user are displayed in red. Once there are
%% no new cache variables created during a configure run, the generate
%% button is enabled.
コマンドを実行するとキャッシュ変数の値が書き変わるので、
最終的なビルドをとりまとめる処理は漸進的に行える。
たとえば、あるオプションを有効にするまで別の追加オプションは見えないといった具合だ。
そのため、ユーザーがすべてのオプションを少なくとも一度は見るまでは
GUIの``generate''ボタンを無効にしている。
configureボタンを押すたびに、まだユーザーに見えていないキャッシュ変数が赤く表示される。
赤く表示されるキャッシュ変数がなくなった時点でgenerateボタンが使えるようになる。

\end{aosasect2}

%% \begin{aosasect2}{Testing CMake}
\begin{aosasect2}{CMakeのテスト}

%% Any new CMake developer is first introduced to the testing process
%% used in CMake development. The process makes use of the CMake family
%% of tools (CMake, CTest, CPack, and CDash).  As the code is developed
%% and checked into the version control system, continuous integration
%% testing machines automatically build and test the new CMake code using
%% CTest. The results are sent to a CDash server which notifies
%% developers via email if there are any build errors, compiler warnings,
%% or test failures.
CMake自体の開発に新たに加わった人が最初に見せられるのが、
CMakeの開発におけるテストの手順である。ここではCMakeファミリーのツール群
(CMake、CTest、CPackそしてCDash)を使っている。
コードを書いてバージョン管理システムにチェックインすると、
継続的インテグレーション用のテストマシンが自動的に
新たなCMakeのビルドとテストを(CTestを使って)行う。
その結果はCDashサーバーに送られ、もしビルドエラーや
コンパイル時の警告あるいはテストの失敗などが発生していれば
開発者にメールを送信する。

%% The process is a classic continuous integration testing system. As new
%% code is checked into the CMake repository, it is automatically tested
%% on the platforms supported by CMake. Given the large number of
%% compilers and platforms that CMake supports, this type of testing
%% system is essential to the development of a stable build system.
一連の流れは、典型的な継続的インテグレーション環境と同じだ。
CMakeのリポジトリに新しいコードがチェックインされたら
CMakeがサポートする各種プラットフォーム上でのテストが自動的に行われる。
CMakeはさまざまなコンパイラやプラットフォームに対応しているので、
安定したビルドシステムの開発には
この種のテストシステムが必要となる。

%% For example, if a new developer wants to add support for a new
%% platform, the first question he or she is asked is whether they can
%% provide a nightly dashboard client for that system. Without constant
%% testing, it is inevitable that new systems will stop working after
%% some period of time.
たとえば、誰かが新たなプラットフォームをサポートしたいと思ったとしよう。
その人が最初に聞かれるのは、そのプラットフォーム用の日々のダッシュボード
クライアントを用意できるのかどうかということだ。継続的なテストができなければ、
新たなシステムのサポートなど不可能だ。

\end{aosasect2}

\end{aosasect1}

%% \begin{aosasect1}{Lessons Learned}
\begin{aosasect1}{教訓}

%% CMake was successfully building ITK from day one, and that was the
%% most important part of the project. If we could redo the development
%% of CMake, not much would change. However, there are always things that
%% could have been done better.
CMakeはITKの開発初日から無事に動き出した。
そして、そのプロジェクトで最も重要な位置を占めるようになった。
もし仮にCMakeを一から作り直すことになったとしても、
今と大きくは変えないだろう。とはいえ、
こうしておけばよかったということがないわけではない。

%% \begin{aosasect2}{Backwards Compatibility}
\begin{aosasect2}{後方互換性}

%% Maintaining backwards compatibility is important to the CMake
%% development team. The main goal of the project is to make building
%% software easier. When a project or developer chooses CMake for a build
%% tool, it is important to honor that choice and try very hard to not
%% break that build with future releases of CMake. CMake 2.6 implemented
%% a policy system where changes to CMake that would break existing
%% behavior will warn but still perform the old behavior. Each
%% \code{CMakeLists.txt} file is required to specify which version of
%% CMake they are expecting to use.  Newer versions of CMake might warn,
%% but will still build the project as older versions did.
後方互換性を維持することは、CMake開発チームにとって重要なことだった。
このプロジェクトの第一の目標は、ソフトウェアのビルドを容易にすることである。
どこかのプロジェクトや開発者がビルドツールとしてCMakeを採用したとして、
そのときに重要なのは、CMakeのバージョンを上げたとたんにビルドできなくなる
などという事態を何としてでも避けるということだ。
CMake 2.6ではポリシーシステムを導入した。
これは、CMakeの既存の振る舞いを変えてしまうような変更をすると
警告を発して今までの振る舞いをし続けるというものだ。これを使うには、
使おうとしているCMakeのバージョンを
\code{CMakeLists.txt}ファイルで指定しておく必要がある。
新しいバージョンのCMakeでビルドすると警告が発生するが、
古いバージョンのときと同じ動きでビルドが進む。

\end{aosasect2}

%% \begin{aosasect2}{Language, Language, Language}
\begin{aosasect2}{言語、げんご、ゲンゴ}

%% The CMake language is meant to be very simple. However, it is one of
%% the major obstacles to adoption when a new project is considering
%% CMake. Given its organic growth, the CMake language does have a few
%% quirks. The first parser for the language was not even lex/yacc based
%% but rather just a simple string parser. Given the chance to do the
%% language over, we would have spent some time looking for a nice
%% embedded language that already existed. Lua is the best fit that might
%% have worked. It is very small and clean. Even if an external language
%% like Lua was not used, I would have given more consideration to the
%% existing language from the start.
CMake言語は、とにかくシンプルなものにするという方針で作った。
しかしそれが、新たなプロジェクトでCMakeの採用を検討するにあたっての
大きな障害になることが多かった。
現在のCMake言語には、いくつかおかしな動きがある。
最初のパーサーはlex/yaccすら使っておらず、
単に文字列をパースするだけのものだった。
CMake言語について考え直すチャンスがあれば、
既に存在するよくできた組み込み言語を調査しただろう。
一番相性がよさそうなのは、きっとLuaだ。
コンパクトにまとまっていて、すっきりとしている。
Luaのような外部の言語を使わないにしても、
既存の言語をもっと早いうちから調べるべきだった。

\end{aosasect2}

%% \begin{aosasect2}{Plugins Did Not Work}
\begin{aosasect2}{プラグインが動かない!}

%% To provide the ability for extension of the CMake language by
%% projects, CMake has a plugin class. This allows a project to create
%% new CMake commands in C. This sounded like a good idea at
%% the time, and the interface was defined for C so that different
%% compilers could be used. However, with the advent of multiple API
%% systems like 32/64 bit Windows and Linux, the compatibility of plugins
%% became hard to maintain. While extending CMake with the CMake language
%% is not as powerful, it avoids CMake crashing or not being able
%% to build a project because a plugin failed to build or load.
CMake言語をプロジェクトごとに拡張できるように、プラグインクラスを用意している。
これを使えば、各プロジェクト用の新たなCMakeコマンドをCで作れる。
この機能を作った当時はよさげなアイデアに思えたし、
インターフェイスはC用に定義したのでさまざまなコンパイラで使えた。
しかし、32ビット/64ビットのWindowsやLinuxなどのさまざまなAPIシステムが登場し、
プラグインの互換性を維持するのが難しくなってきた。
プラグインを使わずにCMakeの言語だけでCMakeを拡張するのはあまり強力な仕組みではないが、
プラグインのビルドや読み込みに失敗したせいでCMakeがクラッシュしたり
プロジェクトがビルドできなかったりといったことは回避できる。

\end{aosasect2}

%% \begin{aosasect2}{Reduce Exposed APIs}
\begin{aosasect2}{公開APIの削減}

%% A big lesson learned during the development of the CMake project is
%% that you don't have to maintain backward compatibility with something
%% that users don't have access to. Several times during the development
%% of CMake, users and customers requested that CMake be made into a
%% library so that other languages could be bound to the CMake
%% functionality. Not only would this have fractured the CMake user
%% community with many different ways to use CMake, but it would have
%% been a huge maintenance cost for the CMake project.
CMakeの開発で得た大きな教訓は、
ユーザーが使いもしない機能の後方互換性をわざわざ維持する必要などないということだ。
CMakeの開発中に何度か、ユーザーや顧客から「CMake自体をライブラリ化して
他の言語からその機能を使えるようにしてほしい」という要望を受けた。
そんなことをすれば、いろんな使い方をする人たちが出てきてCMakeのユーザーコミュニティが
分断されるし、さらにCMakeプロジェクトのメンテナンスコストも増大してしまう。

\end{aosasect2}

\end{aosasect1}

\end{aosachapter}
